package org.jeecg.modules.wmhb.controller;

import java.util.*;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.UserConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.wmhb.entity.*;
import org.jeecg.modules.wmhb.service.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;

/**
 * @Description: 采购任务书BOM
 * @Author: jeecg-boot
 * @Date: 2024-08-31
 * @Version: V1.0
 */
@Api(tags = "采购任务书BOM")
@RestController
@RequestMapping("/wmhb/wmPurchaseTaskbookBom")
@Slf4j
public class WmPurchaseTaskbookBomController extends JeecgController<WmPurchaseTaskbookBom, IWmPurchaseTaskbookBomService> {
    @Autowired
    private IWmPurchaseTaskbookBomService wmPurchaseTaskbookBomService;
    @Autowired
    private IWmTaskbookService wmTaskbookService;
    @Autowired
    private IWmTaskService wmTaskService;
    @Autowired
    private IWmFlowDeptService wmFlowDeptService;
    @Autowired
    private IWmTaskFlowService wmTaskFlowService;
    @Autowired
    private IWmTaskLogService wmTaskLogService;

    /**
     * 分页列表查询
     *
     * @param wmPurchaseTaskbookBom
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "采购任务书BOM-分页列表查询")
    @ApiOperation(value = "采购任务书BOM-分页列表查询", notes = "采购任务书BOM-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<WmPurchaseTaskbookBom>> queryPageList(WmPurchaseTaskbookBom wmPurchaseTaskbookBom,
                                                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                              @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                              HttpServletRequest req) {
        QueryWrapper<WmPurchaseTaskbookBom> queryWrapper = QueryGenerator.initQueryWrapper(wmPurchaseTaskbookBom, req.getParameterMap());
        Page<WmPurchaseTaskbookBom> page = new Page<WmPurchaseTaskbookBom>(pageNo, pageSize);
        IPage<WmPurchaseTaskbookBom> pageList = wmPurchaseTaskbookBomService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 添加
     *
     * @param wmPurchaseTaskbookBom
     * @return
     */
    @AutoLog(value = "采购任务书BOM-添加")
    @ApiOperation(value = "采购任务书BOM-添加", notes = "采购任务书BOM-添加")
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody WmPurchaseTaskbookBom wmPurchaseTaskbookBom) {
        wmPurchaseTaskbookBomService.save(wmPurchaseTaskbookBom);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param wmPurchaseTaskbookBom
     * @return
     */
    @AutoLog(value = "采购任务书BOM-编辑")
    @ApiOperation(value = "采购任务书BOM-编辑", notes = "采购任务书BOM-编辑")
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody WmPurchaseTaskbookBom wmPurchaseTaskbookBom) {
        wmPurchaseTaskbookBomService.updateById(wmPurchaseTaskbookBom);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "采购任务书BOM-通过id删除")
    @ApiOperation(value = "采购任务书BOM-通过id删除", notes = "采购任务书BOM-通过id删除")
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        wmPurchaseTaskbookBomService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "采购任务书BOM-批量删除")
    @ApiOperation(value = "采购任务书BOM-批量删除", notes = "采购任务书BOM-批量删除")
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:deleteBatch")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.wmPurchaseTaskbookBomService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "采购任务书BOM-通过id查询")
    @ApiOperation(value = "采购任务书BOM-通过id查询", notes = "采购任务书BOM-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<WmPurchaseTaskbookBom> queryById(@RequestParam(name = "id", required = true) String id) {
        WmPurchaseTaskbookBom wmPurchaseTaskbookBom = wmPurchaseTaskbookBomService.getById(id);
        if (wmPurchaseTaskbookBom == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(wmPurchaseTaskbookBom);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param wmPurchaseTaskbookBom
     */
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, WmPurchaseTaskbookBom wmPurchaseTaskbookBom, @RequestParam(name = "wmTaskId", required = true) String wmTaskId) {
        List<WmPurchaseTaskbookBom> wmPurchaseTaskbookBomList = wmPurchaseTaskbookBomService.listByWmTaskId(wmTaskId);
        if(wmPurchaseTaskbookBomList.isEmpty()){
            throw new RuntimeException("当前任务没有物料");
        }
        return wmPurchaseTaskbookBomService.exportBomExcel(request, wmPurchaseTaskbookBomList);
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:importExcel")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, WmPurchaseTaskbookBom.class);
    }

    /**
     * 查询采购BOM
     * @param wmTaskbookId
     * @param wmTaskId
     * @return
     */
    //@AutoLog(value = "采购任务书BOM-查询采购BOM")
    @ApiOperation(value = "采购任务书BOM-查询采购BOM", notes = "采购任务书BOM-查询采购BOM")
    @GetMapping(value = "/queryPurchaseBom")
    public Result<List<WmPurchaseTaskbookBom>> queryPurchaseBom(@RequestParam(name = "wmTaskbookId", required = true) String wmTaskbookId, @RequestParam(name = "wmTaskId", required = false) String wmTaskId) {
        LambdaQueryWrapper<WmPurchaseTaskbookBom> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmPurchaseTaskbookBom::getWmTaskbookId, wmTaskbookId);
        if(!StringUtils.isEmpty(wmTaskId)){
            queryWrapper.eq(WmPurchaseTaskbookBom::getWmTaskId, wmTaskId);
        }
        List<WmPurchaseTaskbookBom> wmPurchaseTaskbookBomList = wmPurchaseTaskbookBomService.list(queryWrapper);
        List<WmPurchaseTaskbookBom> wmPurchaseTaskbookBomListNew = new ArrayList<>();
        for(WmPurchaseTaskbookBom wmPurchaseTaskbookBom: wmPurchaseTaskbookBomList){
            WmTaskbook wmTaskbook = wmTaskbookService.getById(wmPurchaseTaskbookBom.getWmTaskbookId());
            wmPurchaseTaskbookBom.setWmTaskbook(wmTaskbook);
            wmPurchaseTaskbookBomListNew.add(wmPurchaseTaskbookBom);
        }
        return Result.OK(wmPurchaseTaskbookBomListNew);
    }

    /**
     * 采购BOM到货
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "采购任务书BOM-采购BOM到货")
    @ApiOperation(value = "采购任务书BOM-采购BOM到货", notes = "采购任务书BOM-采购BOM到货")
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:arriveItem")
    @RequestMapping(value = "/arriveItem", method = {RequestMethod.PUT, RequestMethod.POST})
    @Transactional
    public Result<String> arriveItem(@RequestParam(name = "ids", required = true) String ids) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        WmTask wmTask = null;
        List<String> idList = Arrays.asList(ids.split(","));
        for(String id: idList) {
            WmPurchaseTaskbookBom wmPurchaseTaskbookBom = wmPurchaseTaskbookBomService.getById(id);
            wmPurchaseTaskbookBom.setStatus(UserConstant.PURCHASE_TASKBOOK_STATUS_ARRIVED); //更新任务的状态为到货
            wmPurchaseTaskbookBomService.updateById(wmPurchaseTaskbookBom);
            if(wmTask ==  null) {
                wmTask = wmTaskService.getById(wmPurchaseTaskbookBom.getWmTaskId());
            }
        }

        //判断所有采购BOM是否都到货了
        Boolean allArrive = true;
        List<WmPurchaseTaskbookBom> wmPurchaseTaskbookBomList = wmPurchaseTaskbookBomService.listByWmTaskId(wmTask.getId());
        for(WmPurchaseTaskbookBom wmPurchaseTaskbookBom: wmPurchaseTaskbookBomList){
            if(!wmPurchaseTaskbookBom.getStatus().equals(UserConstant.PURCHASE_TASKBOOK_STATUS_ARRIVED) && !wmPurchaseTaskbookBom.getStatus().equals(UserConstant.PURCHASE_TASKBOOK_STATUS_FINISHED)){
                allArrive = false;
                break;
            }
        }

        //更新任务为到货状态
        if(allArrive){
            wmTask.setStatus(UserConstant.TASK_STATUS_ARRIVED);
            wmTask.setProgress("90");//已到货算90%
            wmTask.setStorageUserId(sysUser.getId());
            nextFlowTask(wmTask);

            //更新任务日志
            wmTaskLogService.updateTaskLog(wmTask.getId(), UserConstant.TASK_LOG_TYPE_BOM_REACHED);
        }

        return Result.OK("操作成功");
    }

    /**
     * 任务采购BOM到货
     *
     * @param wmTaskId
     * @return
     */
    @AutoLog(value = "采购任务BOM-任务采购BOM到货")
    @ApiOperation(value = "采购任务BOM-任务采购BOM到货", notes = "采购任务BOM-任务采购BOM到货")
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:arriveByTask")
    @Transactional
    @RequestMapping(value = "/arriveByTask", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> arriveByTask(@RequestParam(name = "wmTaskId", required = true) String wmTaskId) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        wmPurchaseTaskbookBomService.arriveByTask(wmTaskId);
        WmTask wmTask = wmTaskService.getById(wmTaskId);
        wmTask.setStatus(UserConstant.TASK_STATUS_ARRIVED);
        wmTask.setProgress("90");//已到货算90%
        wmTask.setStorageUserId(sysUser.getId());
        nextFlowTask(wmTask);

        //更新任务日志
        wmTaskLogService.updateTaskLog(wmTask.getId(), UserConstant.TASK_LOG_TYPE_BOM_REACHED);

        return Result.OK("操作成功");
    }

    /**
     * 采购BOM已采购
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "采购任务书BOM-采购BOM已采购")
    @ApiOperation(value = "采购任务书BOM-采购BOM已采购", notes = "采购任务书BOM-采购BOM已采购")
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:purchaseItem")
    @RequestMapping(value = "/purchaseItem", method = {RequestMethod.PUT, RequestMethod.POST})
    @Transactional
    public Result<String> purchaseItem(@RequestParam(name = "ids", required = true) String ids) {
        WmTask wmTask = null;
        List<String> idList = Arrays.asList(ids.split(","));
        for(String id: idList) {
            WmPurchaseTaskbookBom wmPurchaseTaskbookBom = wmPurchaseTaskbookBomService.getById(id);
            wmPurchaseTaskbookBom.setStatus(UserConstant.PURCHASE_TASKBOOK_STATUS_PURCHASED); //更新任务的状态为已采购
            wmPurchaseTaskbookBom.setPurchaseTime(new Date());
            wmPurchaseTaskbookBomService.updateById(wmPurchaseTaskbookBom);

            wmTask = wmTaskService.getById(wmPurchaseTaskbookBom.getWmTaskId());
        }

        //判断所有采购BOM是否都采购了
        Boolean allPurchase = true;
        List<WmPurchaseTaskbookBom> wmPurchaseTaskbookBomList = wmPurchaseTaskbookBomService.listByWmTaskId(wmTask.getId());
        for(WmPurchaseTaskbookBom wmPurchaseTaskbookBom: wmPurchaseTaskbookBomList){
            if(!wmPurchaseTaskbookBom.getStatus().equals(UserConstant.PURCHASE_TASKBOOK_STATUS_PURCHASED) && !wmPurchaseTaskbookBom.getStatus().equals(UserConstant.PURCHASE_TASKBOOK_STATUS_ARRIVED)  && !wmPurchaseTaskbookBom.getStatus().equals(UserConstant.PURCHASE_TASKBOOK_STATUS_FINISHED)){
                allPurchase = false;
                break;
            }
        }

        //更新任务为采购状态
        if(allPurchase){
            wmTask.setStatus(UserConstant.TASK_STATUS_PURCHASED);
            wmTask.setProgress("70");//已采购算70%
            nextFlowTask(wmTask);

            //更新任务日志
            wmTaskLogService.updateTaskLog(wmTask.getId(), UserConstant.TASK_LOG_TYPE_BOM_PURCHASE);
        }

        return Result.OK("操作成功");
    }

    /**
     * 任务采购BOM已采购
     *
     * @param wmTaskId
     * @return
     */
    @AutoLog(value = "采购任务BOM-任务采购BOM已采购")
    @ApiOperation(value = "采购任务BOM-任务采购BOM已采购", notes = "采购任务BOM-任务采购BOM已采购")
    @RequiresPermissions("wmhb:wm_purchase_taskbook_bom:purchaseByTask")
    @Transactional
    @RequestMapping(value = "/purchaseByTask", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> purchaseByTask(@RequestParam(name = "wmTaskId", required = true) String wmTaskId) {
        wmPurchaseTaskbookBomService.purchaseByTask(wmTaskId);
        WmTask wmTask = wmTaskService.getById(wmTaskId);
        wmTask.setStatus(UserConstant.TASK_STATUS_PURCHASED);
        wmTask.setProgress("70");//已采购算70%
        nextFlowTask(wmTask);

        //更新任务日志
        wmTaskLogService.updateTaskLog(wmTask.getId(), UserConstant.TASK_LOG_TYPE_BOM_PURCHASE);

        return Result.OK("操作成功");
    }

    /**
     * 任务下一流程
     * @param wmTask
     * @return
     */
    private void nextFlowTask(WmTask wmTask){
        WmTaskbook wmTaskbook = wmTaskbookService.getById(wmTask.getWmTaskbookId());
        //1、流程部门列表
        List<WmFlowDept> wmFlowDeptList = wmFlowDeptService.selectByMainId(wmTaskbook.getWmTaskbookFlowId());

        //2、下一流程
        Integer nextIndex = wmTask.getCurrentNodeIndex() + 1;
        if(nextIndex >= wmFlowDeptList.size()){
            throw new RuntimeException("请补充完整的流程定义");
        }
        wmTask.setCurrentNodeIndex(nextIndex);
        wmTask.setCurrentNodeId(wmFlowDeptList.get(nextIndex).getDeptId());
        wmTask.setCurrentNodeTime(new Date());
        wmTaskService.updateById(wmTask);

        //3、设置上一流程实际结束时间和当前流程实际开始时间
        WmTaskFlow wmTaskFlowCurr = wmTaskFlowService.getTaskFlowByTaskAndOrder(wmTask.getId(), nextIndex-1);
        WmTaskFlow wmTaskFlowNext = wmTaskFlowService.getTaskFlowByTaskAndOrder(wmTask.getId(), nextIndex);
        wmTaskFlowCurr.setFactEndTime(new Date());
        wmTaskFlowNext.setFactBeginTime(new Date());
        wmTaskFlowService.updateById(wmTaskFlowCurr);
        wmTaskFlowService.updateById(wmTaskFlowNext);

        //4、更新任务书当前流程部门
        if(wmTask.getAncestors().equals(UserConstant.ANCESTOR_ZERO)) {
            wmTaskbook.setCurrentNodeIndex(nextIndex);
            wmTaskbook.setCurrentNodeId(wmFlowDeptList.get(nextIndex).getDeptId());
            wmTaskbook.setProgress(wmTask.getProgress());
            wmTaskbook.setStatus(wmTask.getStatus());
            wmTaskbookService.updateById(wmTaskbook);
        }
    }

    /**
     * 任务上一流程
     * @param wmTask
     * @return
     */
    private void prevFlowTask(WmTask wmTask){
        WmTaskbook wmTaskbook = wmTaskbookService.getById(wmTask.getWmTaskbookId());
        //1、流程部门列表
        List<WmFlowDept> wmFlowDeptList = wmFlowDeptService.selectByMainId(wmTaskbook.getWmTaskbookFlowId());

        //2、上一流程
        Integer prevIndex = wmTask.getCurrentNodeIndex() - 1;
        if(prevIndex < 0){
            throw new RuntimeException("流程异常");
        }
        wmTask.setCurrentNodeIndex(prevIndex);
        wmTask.setCurrentNodeId(wmFlowDeptList.get(prevIndex).getDeptId());
        wmTask.setCurrentNodeTime(new Date());
        wmTaskService.updateById(wmTask);

        //3、设置上一流程实际结束时间和当前流程实际开始时间
        WmTaskFlow wmTaskFlowPrev = wmTaskFlowService.getTaskFlowByTaskAndOrder(wmTask.getId(), prevIndex);
        WmTaskFlow wmTaskFlowCurr = wmTaskFlowService.getTaskFlowByTaskAndOrder(wmTask.getId(), prevIndex + 1);
        wmTaskFlowPrev.setFactEndTime(null);
        wmTaskFlowCurr.setFactBeginTime(null);
        wmTaskFlowService.updateById(wmTaskFlowPrev);
        wmTaskFlowService.updateById(wmTaskFlowCurr);

        //4、更新任务书当前流程部门
        if(wmTask.getAncestors().equals(UserConstant.ANCESTOR_ZERO)) {
            wmTaskbook.setCurrentNodeIndex(prevIndex);
            wmTaskbook.setCurrentNodeId(wmFlowDeptList.get(prevIndex).getDeptId());
            wmTaskbook.setProgress(wmTask.getProgress());
            wmTaskbook.setStatus(wmTask.getStatus());
            wmTaskbookService.updateById(wmTaskbook);
        }
    }
}
